In modern programming, it is common for routine calls to be deeply nested. The processor state, as at least partially reflected by the values stored in a number of different registers, is generally saved on a system stack by a calling routine, so that a called routine can freely use register resources for the called routine's computations, and so that the processor state of the calling routine can be restored when the called routine completes. Deeply nested routine calls are reflected in a corresponding large number of stack frames stacked in a system stack. When problems arise, and processes are aborted or debuggers invoked, the values of stacked registers are crucial for tracing back through nested routine calls in order to determine the sequence of events leading to the error. Currently, compliers and assemblers separately generate copious amounts of debug information that is stored in memory during execution of processes in order to facilitate recovery of the register value states of nested routine calls in the event of an error condition or during breakpoint—facilitated analysis or program execution behavior. This stored information is needed both to interpret any values recoverable from a system stack and to replace information lost as a result of memory corruption or loss resulting from an error condition.
The approach of storing additional information in memory to facilitate recovery of stacked register values has several disadvantages. First, this method requires that source code is compiled, or assembly code assembled, with correct options to generate the additional debug information stored in memory. Unfortunately, it is frequently the case that the correct options have not been selected, and yet an important error needs to be debugged without the ability to recompile the code with the appropriate debugging options. A second disadvantage is that the loader employed to link compiled programs into executables must allocate additional space in memory to hold the debug information when the debug options are enabled during compilation and assembly. It can be the case that allocation of additional memory sufficiently changes the computing environment to mask error conditions that would arise when code compiled without debug options is executed. However, in many cases, the debug options cannot be used for compiling production systems, because of the inefficiencies of added instructions and the additional needed memory space. An additional disadvantage is that, even when debugging options are desired, it may be inefficient or impossible for the linker to allocate the additional memory space needed for debugging, depending on the constraints of the computer system and the execution environment. For these reasons, designers, developers, manufacturers, and users of programming tools, including compilers, assemblers, and debugging environments have recognized the need for alternative methods for recovering stacked register values for nested routines in order to facilitate debugging and system analysis.